package com.yupi.springbootinit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.mapper.UserMapper;
import com.yupi.springbootinit.model.dto.user.UserLoginRequest;
import com.yupi.springbootinit.model.dto.user.UserRegisterRequest;
import com.yupi.springbootinit.model.dto.user.UserUpdateRequest;
import com.yupi.springbootinit.model.entity.User;
import com.yupi.springbootinit.model.vo.UserVO;
import com.yupi.springbootinit.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.yupi.springbootinit.constant.UserConstant.USER_LOGIN_STATE;

/**
 *
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService {

    //盐值:加密密码
    private static final String SALT = "hines";

    /**
     * 登录功能
     * @param userLoginRequest
     * @param request
     * @return
     */
    @Override
    public UserVO UserLogin(UserLoginRequest userLoginRequest, HttpServletRequest request) {

        if(userLoginRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();
        if(StringUtils.isBlank(userAccount)){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        if(StringUtils.isBlank(userPassword)){
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }

        //账号不能小于4位
        if(userAccount.length() < 4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        //密码不小于8位
        if(userPassword.length() < 8){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        //不能包含特殊字符
        String vaildPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";//这里表示特殊字符
        Matcher matcher = Pattern.compile(vaildPattern).matcher((userAccount));
        if (matcher.find()) { //找到特殊字符就返回-1
            throw new BusinessException(ErrorCode.PARAMS_ERROR);

        }

        /*获取加密后的密码*/
        String newPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("userAccount",userAccount);
        queryWrapper.eq("userPassword",newPassword);
        User user = this.getOne(queryWrapper);
        if(user == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"无该用户");

        }

        //用户进行脱敏（脱出敏感信息例如密码这些）
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user,userVO);

        //记录当前用户登录状态
        request.getSession().setAttribute(USER_LOGIN_STATE,userVO);

        return userVO;

    }

    /**
     * 注册功能
     * @param userRegisterRequest
     * @return
     */
    @Override
    public long UserRegister(UserRegisterRequest userRegisterRequest) {
        if(userRegisterRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String userName = userRegisterRequest.getName();
        String userAccount = userRegisterRequest.getUserAccount();
        String userPassword = userRegisterRequest.getUserPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();

        //账号不小于4位
        if(userAccount.length() < 4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        /*密码不小于8*/
        if (userPassword.length() < 8 || checkPassword.length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        /*账户不能包含特殊字符*/
        String vaildPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~！@#￥%……&*（）——+|{}【】‘；：”“’。，、？]";//这里表示特殊字符
        Matcher matcher = Pattern.compile(vaildPattern).matcher((userAccount));
        if (matcher.find()) { //找到特殊字符就返回-1
            throw new BusinessException(ErrorCode.PARAMS_ERROR);

        }

        /*校验密码相同*/
        if (!userPassword.equals(checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        /*账号不能重复*/
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userAccount", userAccount);//这里的userAccount是上面形参传过来的，这条语句表示根据这个userAccount查询有多少条语句
        //这里的this是指当前UserServiceImpl的对象
        long count = this.count(queryWrapper);
        if (count > 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        /*密码加密*/
        String newPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());

        /*插入数据到数据库中*/
        User user = new User();
        user.setUsername(userName);
        user.setUserAccount(userAccount);
        user.setUserPassword(newPassword);
        boolean result = this.save(user);
        //如果插入不成功就抛出异常
        if (!result) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        return user.getId(); //因为返回值是long型的id（注册了一个账号就返回一个id）

    }

    /**
     * 获取当前登录用户的信息
     *
     * @param request
     * @return
     */
    @Override
    public UserVO getLoginUser(HttpServletRequest request) {
        if (request == null) {
            return null;
        }

        //获取当前登录用户的信息
        UserVO loginUser = (UserVO) request.getSession().getAttribute(USER_LOGIN_STATE);

        //如果当前登录的用户信息为空，则用户修改的不是自己的信息，抛出异常无权限。
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        return loginUser;
    }

    /**
     * 判断是否为管理员
     * @param request
     * @return
     */
    @Override
    public boolean isAdmin(HttpServletRequest request) {
        UserVO loginUser = this.getLoginUser(request);
        Long id = loginUser.getId();

        User user = this.getById(id);
        if(user.getUserStatus() == 0){
            return true;
        }
        return false;
    }

    /**
     * 写地址
     * @param address
     * @param loginUser
     * @return
     */
    @Override
    public boolean writeAddress(String address, UserVO loginUser) {
        Long userId = loginUser.getId();
        String userAddress = loginUser.getAddress();
        AtomicBoolean flag = new AtomicBoolean(false);
        if(userAddress.equals(address)){
            return true;
        }else{
            LambdaUpdateWrapper<User> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            lambdaUpdateWrapper.eq(User::getId,userId);
            lambdaUpdateWrapper.set(User::getAddress,address);
            flag.set(this.update(lambdaUpdateWrapper));
            return flag.get();
        }
    }

    @Override
    public int UserLogout(HttpServletRequest request) {
        //之前登录时候定义的session的键为常量
        request.getSession().removeAttribute(USER_LOGIN_STATE);
        return 1;
    }

    @Override
    public boolean updateUser(UserUpdateRequest userUpdateRequest, UserVO loginUser) {
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        String userName = userUpdateRequest.getUserName();
        if(StringUtils.isNotBlank(userName)){
            userUpdateWrapper.set("username",userName);
        }
        String phone = userUpdateRequest.getPhone();
        if(StringUtils.isNotBlank(phone)){
            userUpdateWrapper.set("phone",phone);
        }
        String email = userUpdateRequest.getEmail();
        if(StringUtils.isNotBlank(email)){
            userUpdateWrapper.set("email",email);
        }
        String userAvatar = userUpdateRequest.getUserAvatar();
        if(StringUtils.isNotBlank(userAvatar)){
            userUpdateWrapper.set("avatar",userAvatar);
        }
        String profile = userUpdateRequest.getProfile();
        if(StringUtils.isNotBlank(profile)){
            userUpdateWrapper.set("profile",profile);
        }
        Long id = loginUser.getId();
        userUpdateWrapper.eq("id",id);
        boolean result = this.update(userUpdateWrapper);
        return result;
    }

}




